﻿//#region File and License Information
///*
//<File>
//	<License Type="BSD">
//		Copyright © 2009 - 2012, Outcoder. All rights reserved.
//	
//		This file is part of Calcium (http://calciumsdk.net).
//
//		Redistribution and use in source and binary forms, with or without
//		modification, are permitted provided that the following conditions are met:
//			* Redistributions of source code must retain the above copyright
//			  notice, this list of conditions and the following disclaimer.
//			* Redistributions in binary form must reproduce the above copyright
//			  notice, this list of conditions and the following disclaimer in the
//			  documentation and/or other materials provided with the distribution.
//			* Neither the name of the <organization> nor the
//			  names of its contributors may be used to endorse or promote products
//			  derived from this software without specific prior written permission.
//
//		THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
//		ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//		WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
//		DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
//		DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
//		(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//		LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
//		ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
//		(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//		SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//	</License>
//	<Owner Name="Daniel Vaughan" Email="danielvaughan@outcoder.com" />
//	<CreationDate>2010-07-30 17:32:22Z</CreationDate>
//</File>
//*/
//#endregion
//
//using System;
//using System.Diagnostics;
//using System.IO.IsolatedStorage;
//using System.Threading;
//
//using Outcoder.Concurrency;
//using Outcoder.SettingsModel;
//
//namespace Outcoder.Services
//{
//	/// <summary>
//	/// The default implementation of the <see cref="ISettingsService"/>.
//	/// </summary>
//	public class SettingsService : ISettingsService
//	{
//		readonly SettingsEventBroadcaster eventBroadcaster;
//
//		public SettingsService()
//		{
//			eventBroadcaster = new SettingsEventBroadcaster(this);
//		}
//
//		/// <summary>
//		/// Provides thread safety for the dictionary of settings.
//		/// </summary>
//		readonly ReaderWriterLockSlim settingsLockSlim = new ReaderWriterLockSlim();
//
//		/* TODO: Switch to binary serialization. */
//		readonly IsolatedStorageSettings settings 
//			= IsolatedStorageSettings.ApplicationSettings;
//		
//		public T GetSetting<T>(string key, T defaultValue)
//		{
//			ArgumentValidator.AssertNotNull(key, "key");
//
//			return (T)(object)GetSetting(key, typeof(T), defaultValue);
//		}
//
//		public object GetSetting(string key, Type settingType, object defaultValue)
//		{
//			ArgumentValidator.AssertNotNull(key, "key");
//
//			return settingsLockSlim.PerformUsingReadLock(
//				() =>
//			    {
//			        object entry;
//
//					if (settings.TryGetValue(key, out entry))
//					{
//						return entry;
//					}
//
//#if WINDOWS_PHONE
//					var transientState = Microsoft.Phone.Shell.PhoneApplicationService.Current.State;
//					if (transientState.TryGetValue(key, out entry))
//					{
//						return entry;
//					}
//#endif
//				    return defaultValue;
//			    });
//		}
//
//		public bool ContainsSetting(string key)
//		{
//			ArgumentValidator.AssertNotNull(key, "key");
//
//			return settingsLockSlim.PerformUsingReadLock(
//									() => settings.Contains(key));
//		}
//
//		public SetSettingResult SetSetting<T>(string key, T value, bool transient = false)
//		{
//			/* Check to see if the value is already set. 
//			 * This avoids raising events unnecessarily. */
//			bool alreadySet = false;
//			settingsLockSlim.PerformUsingWriteLock(
//				delegate
//				{
//					object existingValue;
//					if (settings.TryGetValue(key, out existingValue))
//					{
//						if (existingValue != null && existingValue.Equals(value))
//						{
//							alreadySet = true;
//							return;
//						}
//					}
//
//					#if WINDOWS_PHONE
//					var transientState = Microsoft.Phone.Shell.PhoneApplicationService.Current.State;
//					if (transientState.TryGetValue(key, out existingValue) && existingValue.Equals(value))
//					{
//						alreadySet = true;
//					}
//					#endif
//				});
//			
//			if (alreadySet)
//			{
//				return SetSettingResult.Successful;
//			}
//
//			/* Allows this action to be cancelled. */
//			var args = new SettingChangingEventArgs(key, value);
//			OnSettingChanging(args);
//
//			if (args.Cancel)
//			{
//				Debug.WriteLine(string.Format(
//					"Setting change cancelled. Key: {0} New Value: {1}", key, value));
//				return SetSettingResult.Cancelled;
//			}
//
//			settingsLockSlim.PerformUsingWriteLock(
//				delegate
//			    {
//					if (!transient)
//					{
//						if (value == null)
//						{
//							settings.Remove(key);
//						}
//						else
//						{
//							settings[key] = value;
//						}
//						settings.Save();
//					}
//					else
//					{
//#if WINDOWS_PHONE
//						var transientState = Microsoft.Phone.Shell.PhoneApplicationService.Current.State;
//						if (value == null)
//						{
//							transientState.Remove(key);
//						}
//						else
//						{
//							transientState[key] = value;
//						}
//#else
//						throw new NotImplementedException();
//#endif
//					}
//			    });
//			OnSettingChanged(new SettingChangingEventArgs(key, value));
//			
//			return SetSettingResult.Successful;
//		}
//
//		public void ClearSettings()
//		{
//			settingsLockSlim.PerformUsingWriteLock(
//				delegate
//				{
//					settings.Clear();
//					settings.Save();
//				});
//		}
//
//		#region event SettingChanging
//
//		public event EventHandler<SettingChangingEventArgs> SettingChanging;
//
//		protected virtual void OnSettingChanging(SettingChangingEventArgs e)
//		{
//			SettingChanging.Raise(this, e);
//		}
//
//		#endregion
//
//		#region event SettingChanged
//
//		public event EventHandler<SettingChangeEventArgs> SettingChanged;
//
//		protected virtual void OnSettingChanged(SettingChangeEventArgs e)
//		{
//			SettingChanged.Raise(this, e);
//		}
//
//		#endregion
//
////		public void StartService(ApplicationServiceContext context)
////		{
////			/* Intentionally left blank. */
////		}
////
////		public void StopService()
////		{
////			settingsLockSlim.PerformUsingWriteLock(
////				delegate
////			        {
////			            try
////			            {
////							settings.Save();
////			            }
////			            catch (ObjectDisposedException)
////			            {
////			                /* Ignore. */
////			            }
////			        });
////		}
////
////		public void Starting()
////		{
////
////		}
////
////		public void Started()
////		{
////
////		}
////
////		public void Exiting()
////		{
////			
////		}
////
////		public void Exited()
////		{
////
////		}
//	}
//}
